﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace PirateMap.Models.cls
{
  public static class Game
  {
    static Game()
    {
      _players = new Dictionary<string, Player>();
    }

    public static void CreateGame()
    {
      _map = new Map();
      _players = new Dictionary<string, Player>();
    }
    public static void CreateGame(IEnumerable<int> mapSizes)
    {
#warning NotImplemented

      GenerateMap(mapSizes);
      _players = new Dictionary<string, Player>();
    }

    private static bool _isStarted;
    private static Map _map;
    private static Dictionary<string, Player> _players;

    private static void GenerateMap(IEnumerable<int> sizeList)
    {
      _map = new Map(sizeList);
    }

    public static void Start()
    {
      if (_map == null || _players == null || !_players.Any())
        throw new InvalidGameOptionsException();

      _isStarted = true;
    }

    public static Player GetPlayerByName(string name)
    {
      return _players.Values.FirstOrDefault(x => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
    }
    public static bool CheckPlayer(string name)
    {
      return _players.Count(x => x.Value.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) > 0;
    }
    public static void AddNewPlayer(Player player)
    {
      if (_isStarted)
        throw new InvalidGameOptionsException();

      if (_players.Values.Count(x => x.Name.Equals(player.Name, StringComparison.OrdinalIgnoreCase)) > 0)
        throw new PlayerExistException();

      var guid = Guid.NewGuid().ToString("N");
      while (_players.ContainsKey(guid))
      {
        guid = Guid.NewGuid().ToString("N");
      }

      player.Id = guid;
      _players.Add(guid, player);
      _map.AddNewPlayer(guid);
    }

    public static string Move(string userId, DirectionTag direction)
    {
      if (!_players.ContainsKey(userId))
        throw new PlayerNotFoundException();

      return _map.Move(userId, direction);
    }
    public static List<string> Move(string userId, IEnumerable<DirectionTag> directions)
    {
      if (!_players.ContainsKey(userId))
        throw new PlayerNotFoundException();

      if (directions == null || !directions.Any())
        return null;

      return directions.Select(direction => _map.Move(userId, direction)).ToList();
    }

    public static Map GetMap()
    {
      return _map;
    }
  }
}